/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.meta.rpc.func;

import com.je.common.base.DynaBean;
import com.je.common.base.exception.PlatformException;
import com.je.common.base.exception.PlatformExceptionEnum;
import com.je.common.base.service.MetaService;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.meta.cache.func.FuncConfigCache;
import com.je.meta.cache.func.FuncInfoCache;
import com.je.meta.cache.func.FuncStaticizeCache;
import org.apache.servicecomb.provider.pojo.RpcSchema;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

@RpcSchema(schemaId = "metaFuncRpcService")
public class MetaFuncRpcServiceImpl implements MetaFuncRpcService {

    /**
     * 功能基础信息
     */
    private static final String FUNC_BASE_COLUMNS = "JE_CORE_FUNCINFO_ID,FUNCINFO_FUNCCODE,FUNCINFO_FUNCNAME,FUNCINFO_ICONCLS,FUNCINFO_ICON,SY_PARENT,SY_PATH,SY_TREEORDERINDEX";
    /**
     * 功能按钮基础信息
     */
    private static final String FUNC_BUTTON_BASE_COLUMNS = "JE_CORE_RESOURCEBUTTON_ID,RESOURCEBUTTON_CODE,RESOURCEBUTTON_NAME,RESOURCEBUTTON_XTYPE,RESOURCEBUTTON_ICONCLS,RESOURCEBUTTON_BIGICONCLS,RESOURCEBUTTON_FUNCINFO_ID,RESOURCEBUTTON_TYPE,RESOURCEBUTTON_FONTICONCLS,RESOURCEBUTTON_CLS,RESOURCEBUTTON_POSITION";

    @Autowired
    private MetaService metaService;
    @Autowired
    private FuncConfigCache funcConfigCache;
    @Autowired
    private FuncInfoCache funcInfoCache;
    @Autowired
    private FuncStaticizeCache funcStaticizeCache;

    @Override
    public List<DynaBean> findFuncAnsButtonBaseInformationByCode(List<String> funcCodeList) {
        List<DynaBean> funcInfoList = metaService.select("JE_CORE_FUNCINFO",
                ConditionsWrapper.builder().selectColumns(FUNC_BASE_COLUMNS)
                        .in("FUNCINFO_FUNCCODE", funcCodeList)
                        .orderByAsc("SY_ORDERINDEX"));

        List<String> funcIdList = new ArrayList<>();
        for (DynaBean eachFuncBean : funcInfoList) {
            funcIdList.add(eachFuncBean.getStr("JE_CORE_FUNCINFO_ID"));
        }

        List<DynaBean> funcButtonList = metaService.select("JE_CORE_RESOURCEBUTTON", ConditionsWrapper.builder()
                .selectColumns(FUNC_BUTTON_BASE_COLUMNS)
                .in("RESOURCEBUTTON_FUNCINFO_ID", funcIdList).orderByAsc("SY_ORDERINDEX"));
        List<DynaBean> funcButtonBeanList;
        for (DynaBean eachFuncBean : funcInfoList) {
            for (DynaBean eachButtonBean : funcButtonList) {
                if (eachFuncBean.getStr("JE_CORE_FUNCINFO_ID").equals(eachButtonBean.getStr("RESOURCEBUTTON_FUNCINFO_ID"))) {
                    if (eachFuncBean.containsKey("buttons")) {
                        funcButtonBeanList = (List<DynaBean>) eachFuncBean.get("buttons");
                    } else {
                        funcButtonBeanList = new ArrayList<>();
                        eachFuncBean.set("buttons", funcButtonBeanList);
                    }
                    funcButtonBeanList.add(eachButtonBean);
                }
            }
        }
        return funcInfoList;
    }

    /**
     * @param allSubFuncRelationList 所有子功能关联集合
     * @param funcIdList             子功能id集合
     * @return
     */
    private List<DynaBean> recursiveQuerySubFunc(List<DynaBean> allSubFuncRelationList, List<String> excludeList, List<String> funcIdList) {
        if (funcIdList == null || funcIdList.isEmpty()) {
            return null;
        }

        List<DynaBean> subFuncList = new ArrayList<>();
        //查询子功能
        for (DynaBean eachAllSubFuncBean : allSubFuncRelationList) {
            if (funcIdList.contains(eachAllSubFuncBean.getStr("FUNCRELATION_FUNCINFO_ID")) && !excludeList.contains(eachAllSubFuncBean.getStr("FUNCRELATION_FUNCID"))) {
                subFuncList.add(eachAllSubFuncBean);
                if ("func".equals(eachAllSubFuncBean.getStr("FUNCRELATION_RELYONTYPE"))) {
                    excludeList.add(eachAllSubFuncBean.getStr("FUNCRELATION_FUNCID"));
                }
            }
        }

        if (subFuncList == null || subFuncList.isEmpty()) {
            return null;
        }

        List<String> newFuncIdList = new ArrayList<>(subFuncList.size());
        for (DynaBean eachBean : subFuncList) {
            newFuncIdList.add(eachBean.getStr("FUNCRELATION_FUNCID"));
        }

        List<DynaBean> newSubFuncBeanList = recursiveQuerySubFunc(allSubFuncRelationList, excludeList, newFuncIdList);
        if (newSubFuncBeanList != null && !newSubFuncBeanList.isEmpty()) {
            subFuncList.addAll(newSubFuncBeanList);
        }
        return subFuncList;
    }

    @Override
    public Map<String, List<DynaBean>> findPermedFuncsAndChildFuncsWithButtonsByFuncCodes(List<String> funcCodeList) {
        List<DynaBean> funcInfoList = metaService.select("JE_CORE_FUNCINFO", ConditionsWrapper.builder()
                .selectColumns(FUNC_BASE_COLUMNS)
                .in("FUNCINFO_FUNCCODE", funcCodeList).orderByAsc("SY_ORDERINDEX"));
        return findPermedFuncsAndChildFuncsWithButtonsByFuncInfos(funcInfoList, null);
    }

    @Override
    public Map<String, List<DynaBean>> findPermedFuncsAndChildFuncsWithButtonsByFuncIds(List<String> funcIdList) {
        List<DynaBean> funcInfoList = metaService.select("JE_CORE_FUNCINFO",
                ConditionsWrapper.builder().selectColumns(FUNC_BASE_COLUMNS).in("JE_CORE_FUNCINFO_ID", funcIdList).orderByAsc("SY_ORDERINDEX"));
        return findPermedFuncsAndChildFuncsWithButtonsByFuncInfos(funcInfoList, funcIdList);
    }

    private Map<String, List<DynaBean>> findPermedFuncsAndChildFuncsWithButtonsByFuncInfos(List<DynaBean> funcInfoList, List<String> funcIdList) {
        Map<String, List<DynaBean>> result = new HashMap<>();
        if (funcInfoList == null || funcInfoList.isEmpty()) {
            result.put("main", new ArrayList<>());
            result.put("child", new ArrayList<>());
            result.put("button", new ArrayList<>());
            return result;
        }

        if (funcIdList == null) {
            funcIdList = new ArrayList<>();
            for (DynaBean eachFunc : funcInfoList) {
                funcIdList.add(eachFunc.getStr("JE_CORE_FUNCINFO_ID"));
            }
        }

        //查找所有子功能关联
        List<DynaBean> allSubFuncRelationList = metaService.select("JE_CORE_FUNCRELATION", ConditionsWrapper.builder().eq("FUNCRELATION_ENABLED", "1").orderByAsc("SY_ORDERINDEX"));
        //递归查找相关子功能关联
        List<DynaBean> subFuncRelationList = recursiveQuerySubFunc(allSubFuncRelationList, new ArrayList<>(), funcIdList);
        for (int i = 0; subFuncRelationList != null && !subFuncRelationList.isEmpty() && i < subFuncRelationList.size(); i++) {
            if (!"func".equals(subFuncRelationList.get(i).getStr("FUNCRELATION_RELYONTYPE"))) {
                continue;
            }
            funcIdList.add(subFuncRelationList.get(i).getStr("FUNCRELATION_FUNCID"));
        }

        List<DynaBean> funcButtonList = metaService.select("JE_CORE_RESOURCEBUTTON", ConditionsWrapper.builder()
                .selectColumns(FUNC_BUTTON_BASE_COLUMNS).ne("RESOURCEBUTTON_DISABLED", "1")
                .in("RESOURCEBUTTON_FUNCINFO_ID", funcIdList).orderByAsc("SY_ORDERINDEX"));
        result.put("main", funcInfoList);
        result.put("child", subFuncRelationList);
        result.put("button", funcButtonList);
        return result;
    }

    @Override
    public Map<String, DynaBean> findSubFuncParentFuncInfos(List<String> subFuncIdList) {
        Map<String, DynaBean> funcInfoMap = new HashMap<>();
        List<DynaBean> subFuncBeanList = metaService.select("JE_CORE_FUNCRELATION", ConditionsWrapper.builder().in("JE_CORE_FUNCRELATION_ID", subFuncIdList));
        if (subFuncBeanList == null || subFuncBeanList.isEmpty()) {
            return funcInfoMap;
        }
        List<String> funcIdList = new ArrayList<>();
        for (DynaBean eachBean : subFuncBeanList) {
            funcIdList.add(eachBean.getStr("FUNCRELATION_FUNCINFO_ID"));
        }

        List<DynaBean> funcInfoList = metaService.select("JE_CORE_FUNCINFO", ConditionsWrapper.builder().in("JE_CORE_FUNCINFO_ID", funcIdList), FUNC_BASE_COLUMNS);
        if (funcInfoList == null || funcInfoList.isEmpty()) {
            return funcInfoMap;
        }

        for (DynaBean eachSubFuncBean : subFuncBeanList) {
            for (DynaBean eachFuncBean : funcInfoList) {
                if (eachSubFuncBean.getStr("FUNCRELATION_FUNCINFO_ID").equals(eachFuncBean.getStr("JE_CORE_FUNCINFO_ID"))) {
                    funcInfoMap.put(eachSubFuncBean.getStr("JE_CORE_FUNCRELATION_ID"), eachFuncBean);
                }
            }
        }

        return funcInfoMap;
    }

    @Override
    public Map<String, String> findFuncProductMap(List<String> funcCodeList) {
        List<DynaBean> funcBeanList = metaService.select("JE_CORE_FUNCINFO", ConditionsWrapper.builder()
                .selectColumns("JE_CORE_FUNCINFO_ID,FUNCINFO_FUNCCODE,SY_PRODUCT_ID")
                .in("FUNCINFO_FUNCCODE", funcCodeList));
        Map<String, String> funcProductMap = new HashMap<>();
        if (funcBeanList != null && !funcBeanList.isEmpty()) {
            for (DynaBean eachBean : funcBeanList) {
                funcProductMap.put(eachBean.getStr("FUNCINFO_FUNCCODE"), eachBean.getStr("SY_PRODUCT_ID"));
            }
        }
        return funcProductMap;
    }

    @Override
    public void disableFormField(String funcCode, String columnCode) {
        DynaBean funcInfoBean = metaService.selectOne("JE_CORE_FUNCINFO", ConditionsWrapper.builder().in("FUNCINFO_FUNCCODE", funcCode), FUNC_BASE_COLUMNS);
        if (funcInfoBean == null) {
            throw new PlatformException("未找到此功能，请确认此功能存在！", PlatformExceptionEnum.UNKOWN_ERROR);
        }

        metaService.executeSql("UPDATE JE_CORE_RESOURCEFIELD SET RESOURCEFIELD_HIDDEN='1',RESOURCEFIELD_REQUIRE='0' WHERE RESOURCEFIELD_FUNCINFO_ID={0} AND RESOURCEFIELD_CODE={1}",
                funcInfoBean.getStr("JE_CORE_FUNCINFO_ID"),columnCode);
        funcConfigCache.removeCache(funcCode);
        funcInfoCache.removeCache(funcCode);
        funcStaticizeCache.removeCache(funcCode);
    }

    @Override
    public void enableFormField(String funcCode, String columnCode) {
        DynaBean funcInfoBean = metaService.selectOne("JE_CORE_FUNCINFO", ConditionsWrapper.builder().in("FUNCINFO_FUNCCODE", funcCode), FUNC_BASE_COLUMNS);
        if (funcInfoBean == null) {
            throw new PlatformException("未找到此功能，请确认此功能存在！", PlatformExceptionEnum.UNKOWN_ERROR);
        }

        metaService.executeSql("UPDATE JE_CORE_RESOURCEFIELD SET RESOURCEFIELD_HIDDEN='0',RESOURCEFIELD_REQUIRE='0' WHERE RESOURCEFIELD_FUNCINFO_ID={0} AND RESOURCEFIELD_CODE={1}",
                funcInfoBean.getStr("JE_CORE_FUNCINFO_ID"),columnCode);
        funcConfigCache.removeCache(funcCode);
        funcInfoCache.removeCache(funcCode);
        funcStaticizeCache.removeCache(funcCode);
    }
}
